package com.gdut.huayan.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gdut.huayan.dao.*;
import com.gdut.huayan.entity.po.*;
import com.gdut.huayan.entity.vo.ActivityStockVo;
import com.gdut.huayan.entity.vo.ActivityVo;
import com.gdut.huayan.entity.vo.CharityPageVo;
import com.gdut.huayan.entity.vo.StockVo;
import com.gdut.huayan.service.CharityPageService;
import com.gdut.huayan.service.exception.BaseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CharityPageServiceImpl extends ServiceImpl<CharityPageMapper, CharityPage> implements CharityPageService {

    @Autowired
    private ActivityMapper activityMapper;

    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private LimitNameMapper limitNameMapper;

    @Autowired
    private LimitMoneyMapper limitMoneyMapper;

    @Autowired
    private MoneyStockMapper moneyStockMapper;

    public boolean save(CharityPage charityPage){
        charityPage.setIsShow(1);
        /*if (charityPage.getType().equals(1)){
            judgeTopSuiXi();
        }*/
        return super.save(charityPage);
    }

    @Override
    public List<CharityPageVo> getAll() {
        //不是管理员为true
        boolean isNotAdmin = true;
        //区分管理员和普通人
        for (GrantedAuthority authority : SecurityContextHolder.getContext().getAuthentication().getAuthorities()) {
            if("SUPER_ADMIN".equals(authority.getAuthority())){
                //是管理员
                isNotAdmin = false;
                break;
            }
        }
        QueryWrapper<CharityPage> wrapper = new QueryWrapper<>();
        if(isNotAdmin){
            wrapper.eq("is_show",1);
        }
        List<CharityPage> charityPages = baseMapper.selectList(wrapper);
        if(charityPages.size() == 0){
            return null;
        }

        //找出所有的activity和stock,和Vo类需要的limitname和limitMoney
        List<Long> activityId = new ArrayList<>();
        for (CharityPage charityPage : charityPages) {
            activityId.add(charityPage.getActivityId());
        }
        //activity and stock find
        List<Activity> activityList = activityMapper.selectBatchIds(activityId);
        List<Stock> stockList = getStockByActivityIds(activityId);
        List<Long> stockIdList = stockList.stream().map(Stock::getId).collect(Collectors.toList());

        //找limitName类
        QueryWrapper<LimitName> nameQuery = new QueryWrapper<>();
        nameQuery.in("activity_id", activityId);
        List<LimitName> nameList = limitNameMapper.selectList(nameQuery);

        //limtMoney和moneystock
        QueryWrapper<MoneyStock> moneyStockQuery = new QueryWrapper<>();
        moneyStockQuery.in("stock_id", stockIdList);
        List<MoneyStock> moneyStockList = moneyStockMapper.selectList(moneyStockQuery);
        List<LimitMoney> limitMoneyList = null;
        if(moneyStockList.size() != 0){
            List<Long> moneyIdList = moneyStockList.stream().map(MoneyStock::getLimitMoneyId).collect(Collectors.toList());
            limitMoneyList = limitMoneyMapper.selectBatchIds(moneyIdList);
        }


        //hash化
        Map<Long,Activity> hashActivity = activityList.stream().collect(Collectors.toMap(Activity::getId,a -> a));
        Map<Long,List<Stock>> hashStock = stockList.stream().collect(Collectors.groupingBy(Stock::getActivityId));
        Map<Long,List<LimitName>> hashName = null;
        if (nameList.size() != 0){
            hashName = nameList.stream().collect(Collectors.groupingBy(LimitName::getActivityId));
        }
        Map<Long,List<MoneyStock>> hashMoneyStock = null;
        Map<Long,LimitMoney> hashLimitMoney = null;
        if(moneyStockList.size() != 0){
            hashMoneyStock = moneyStockList.stream().collect(Collectors.groupingBy(MoneyStock::getStockId));
            hashLimitMoney = limitMoneyList.stream().collect(Collectors.toMap(LimitMoney::getId,lm->lm));
        }

        //封装Vo类
        List<CharityPageVo> result = new ArrayList<>();
        for(CharityPage charityPage : charityPages){
            List<StockVo> stockVoList = new ArrayList<>();
            ActivityVo activityVo = new ActivityVo(hashActivity.get(charityPage.getActivityId()),
                    hashName == null ? null : hashName.get(charityPage.getActivityId()));

            List<Stock> stocks = hashStock.get(activityVo.getActivity().getId());
            if(stocks != null){
                for (Stock stock : stocks) {
                    List<LimitMoney> stockLM = null;
                    if(hashMoneyStock != null){
                        stockLM = new ArrayList<>();
                        for (MoneyStock moneyStock : hashMoneyStock.get(stock.getId())) {
                            stockLM.add(hashLimitMoney.get(moneyStock.getLimitMoneyId()));
                        }
                    }
                    stockVoList.add(new StockVo(stock,stockLM));
                }
            }
            result.add(new CharityPageVo(charityPage,new ActivityStockVo(activityVo,stockVoList)));

        }
        return result;
    }

    public List<Stock> getStockByActivityIds(List<Long> activityIds){
        QueryWrapper<Stock> stockWrapper = new QueryWrapper<>();
        stockWrapper.in("activity_id",activityIds);
        stockWrapper.isNull("festival_id");
        stockWrapper.isNull("location_id");
        return stockMapper.selectList(stockWrapper);
    }

    @Override
    public boolean updateById(CharityPage charityPage){
        /*if(charityPage.getType() != null && charityPage.getType() == 1){
            judgeTopSuiXi();
        }*/
        return super.updateById(charityPage);
    }

    private void judgeTopSuiXi(){
        Integer count = new LambdaQueryChainWrapper<>(baseMapper).eq(CharityPage::getType, 1).count();
        if(count.compareTo(2) != -1){
            throw new BaseException(4000,"置顶随喜活动已满两个，请先取消置顶一个活动在重试");
        }
    }
}
